home *** CD-ROM | disk | FTP | other *** search
-
- #include "main.h"
-
- //------------------------------------------------------------------
- // Name: BSP()
- // Desc: konstruktor
- //------------------------------------------------------------------
- BSP::BSP()
- {
-
- g_pVB = NULL;
-
- Face = NULL;
- Group = NULL;
- Plane = NULL;
- Node = NULL;
- Leaf = NULL;
- Light = NULL;
- g_pLightMap = NULL;
-
- FileBsp = NULL;
-
- NumFaces = 0;
- NumGroups = 0;
- NumPlanes = 0;
- NumNodes = 0;
- NumLeafs = 0;
- NumLights = 0;
- NumLightMaps = 0;
-
- }
-
-
- //------------------------------------------------------------------
- // Name: CleanUp()
- // Desc: destruktor
- //------------------------------------------------------------------
- void BSP::CleanUp()
- {
-
- //
- //vertex buffer
- //
- if (g_pVB != NULL)
- g_pVB->Release();
- g_pVB = NULL;
-
- //
- //group
- //
- if (Group != NULL)
- {
- //znic textury
- for (int i=0;i<NumGroups;i++)
- {
- ClearGroupTextures(i);
- }
-
- delete [] Group;
- }
- Group = NULL;
-
- //
- //face
- //
- if (Face != NULL)
- delete [] Face;
- Face = NULL;
-
- //
- //plane
- //
- if (Plane != NULL)
- delete [] Plane;
- Plane = NULL;
-
- //
- //Node
- //
- if (Node != NULL)
- delete [] Node;
- Node = NULL;
-
- //
- //Leaf
- //
- if (Leaf != NULL)
- delete [] Leaf;
- Leaf = NULL;
-
- //
- //Lights
- //
- if (Light != NULL)
- delete [] Light;
- Light = NULL;
-
- //
- //LightMap
- //
- if (g_pLightMap != NULL)
- {
- for (int i=0;i<NumLightMaps;i++)
- {
- if (g_pLightMap[i] != NULL)
- g_pLightMap[i]->Release();
- g_pLightMap[i] = NULL;
- }
- delete [] g_pLightMap;
- g_pLightMap = NULL;
- }
-
- }
-
- //------------------------------------------------------------------
- // Name: InitializeGroupTextures()
- // Desc: Inicializuje textury skupiny
- //------------------------------------------------------------------
- void BSP::InitializeGroupTextures(int Index)
- {
- Group[Index].g_pTexture = NULL;
- }
-
-
- //------------------------------------------------------------------
- // Name: ClearGroupTextures()
- // Desc: zmaze textury skupiny
- //------------------------------------------------------------------
- void BSP::ClearGroupTextures(int Index)
- {
- if(Group[Index].g_pTexture != NULL)
- Group[Index].g_pTexture->Release();
- Group[Index].g_pTexture = NULL;
-
- }
-
-
- //------------------------------------------------------------------
- // Name: Load()
- // Desc: loadne BSP strom
- //------------------------------------------------------------------
- void BSP::Load(char *FileName)
- {
-
- char cBuf[80];
- int i;
-
- ///////
- //LOG//
- ///////
- LogPrint("Loading BSP tree...");
- sprintf(cBuf," File: %s",FileName);
- LogPrint(cBuf);
-
-
- ////////
- //FILE//
- ////////
- FileBsp = fopen(FileName,"rb");
- if (FileBsp == NULL)
- {
- sprintf(cBuf," Missing File: %s",FileName);
- LogPrint(cBuf);
- }
-
- /////////
- //Group//
- /////////
- fread(&NumGroups,sizeof(int),1,FileBsp);
- sprintf(cBuf," NumGroups: %d",NumGroups);
- LogPrint(cBuf);
- Group = new BSPGROUP[NumGroups];
- for (i=0;i<NumGroups;i++)
- {
- ReadGroup();
- }
-
- ////////
- //Face//
- ////////
- fread(&NumFaces,sizeof(int),1,FileBsp);
- sprintf(cBuf," NumFaces: %d",NumFaces);
- LogPrint(cBuf);
- Face = new BSPFACE[NumFaces];
- for (i=0;i<NumFaces;i++)
- {
- ReadFace();
- }
-
- /////////
- //Plane//
- /////////
- fread(&NumPlanes,sizeof(int),1,FileBsp);
- sprintf(cBuf," NumPlanes: %d",NumPlanes);
- LogPrint(cBuf);
- Plane = new PLANE[NumPlanes];
- for (i=0;i<NumPlanes;i++)
- {
- ReadPlane();
- }
-
- /////////
- //Node //
- /////////
- fread(&NumNodes,sizeof(int),1,FileBsp);
- sprintf(cBuf," NumNodes: %d",NumNodes);
- LogPrint(cBuf);
- Node = new BSPNODE[NumNodes];
- for (i=0;i<NumNodes;i++)
- {
- ReadNode();
- }
-
- /////////
- //Leaf //
- /////////
- fread(&NumLeafs,sizeof(int),1,FileBsp);
- sprintf(cBuf," NumLeaf: %d",NumLeafs);
- LogPrint(cBuf);
- Leaf = new BSPLEAF[NumNodes];
- for (i=0;i<NumLeafs;i++)
- {
- ReadLeaf();
- }
-
- /////////
- //Light//
- /////////
- fread(&NumLights,sizeof(int),1,FileBsp);
- sprintf(cBuf," NumLights: %d",NumLights);
- LogPrint(cBuf);
- Light = new BSPLIGHT[NumLights];
- for (i=0;i<NumLights;i++)
- {
- ReadLight();
- }
-
- ///////////
- //LighMap//
- ///////////
- fread(&NumLightMaps,sizeof(int),1,FileBsp);
- sprintf(cBuf," NumLightMaps: %d",NumLightMaps);
- LogPrint(cBuf);
- g_pLightMap = new LPDIRECT3DTEXTURE9[NumLightMaps];
- for (i=0;i<NumLightMaps;i++)
- {
- ReadLightMap();
- }
-
-
- ////////////////
- //VertexBuffer//
- ////////////////
- CreateVertexBuffer();
-
-
- fclose(FileBsp);
-
-
- }
-
-
- //------------------------------------------------------------------
- // Name: ReadFace()
- // Desc: precita face
- //------------------------------------------------------------------
- void BSP::ReadFace()
- {
-
- RBSPFACE F;
- int Index;
-
- fread(&F,sizeof(RBSPFACE),1,FileBsp);
- Index = F.Index ;
-
- Face[Index].Group = F.Group;
- Face[Index].Plane = F.Plane;
-
- for(int i=0;i<3;i++)
- {
- Face[Index].P[i] = F.P[i];
- Face[Index].T1[i] = F.T1[i];
- Face[Index].T2[i] = F.T2[i];
- }
-
- }
-
-
- //------------------------------------------------------------------
- // Name: ReadGroup()
- // Desc: nacita skupinu
- //------------------------------------------------------------------
- void BSP::ReadGroup()
- {
-
- RBSPGROUP G;
- char cBuf[80];
- int Index;
-
- fread(&G,sizeof(RBSPGROUP),1,FileBsp);
-
- Index = G.Index ;
-
- LogPrint(" Creating GROUP");
- sprintf(cBuf," Texture: %s",G.Texture);
- LogPrint(cBuf);
-
- Group[Index].BlendType = G.BlendType;
- Group[Index].CollisionType = G.CollisionType;
- Group[Index].Type = G.Type ;
-
- //loadne texturu
- if (FAILED(D3DXCreateTextureFromFileEx(g_pd3dDevice,
- G.Texture ,
- D3DX_DEFAULT,
- D3DX_DEFAULT,
- Engine.MipMapLevels, //MipLevels
- 0,
- Engine.TextureFormat,
- D3DPOOL_MANAGED,
- D3DX_DEFAULT, //Filter
- D3DX_DEFAULT, //MipFilter
- 0xffff00ff, //ColorKey
- NULL,
- NULL,
- &Group[Index].g_pTexture)))
- {
- LogPrint(" FAILED");
- }
-
-
- }
-
- //------------------------------------------------------------------
- // Name: ReadPlane()
- // Desc: nacita roviny
- //------------------------------------------------------------------
- void BSP::ReadPlane()
- {
- int Index;
- RBSPPLANE P;
-
- fread(&P,sizeof(RBSPPLANE),1,FileBsp);
-
- Index = P.Index ;
-
- Plane[Index].D = P.D;
- Plane[Index].Normal = P.Normal;
-
- }
-
- //------------------------------------------------------------------
- // Name: ReadLight()
- // Desc: nacita svetlo
- //------------------------------------------------------------------
- void BSP::ReadLight()
- {
- int Index;
- RBSPLIGHT L;
-
- fread(&L,sizeof(RBSPLIGHT),1,FileBsp);
-
- Index = L.Index ;
-
- Light[Index].Color = L.Color;
- Light[Index].Intensity = L.Intensity;
- Light[Index].Pos = L.Pos;
- Light[Index].Range = L.Range;
-
- }
-
- //------------------------------------------------------------------
- // Name: ReadLight()
- // Desc: nacita lightmapu
- //------------------------------------------------------------------
- void BSP::ReadLightMap()
- {
- int Index;
- RBSPLIGHTMAP L;
-
- fread(&L,sizeof(RBSPLIGHTMAP),1,FileBsp);
-
- Index = L.Index;
-
- //log
- char cBuf[80];
- sprintf(cBuf," Vytvaram LightMapu ID: %d",Index);
- LogPrint(cBuf);
-
- //vynuluje
- g_pLightMap[Index] = NULL;
-
- //vytvori lightmapu
- if (FAILED(D3DXCreateTexture(g_pd3dDevice,256,256,0,0,D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,&g_pLightMap[Index])))
- {
- LogPrint(" chyba");
- }
- else
- {
- LogPrint(" OK");
- }
-
- //skopiruj do lightmapy
- D3DSURFACE_DESC pDesc;
- D3DLOCKED_RECT d3dlr;
- g_pLightMap[Index]->GetLevelDesc(0, &pDesc );
-
- LogPrint(" Otvaram lightmapu");
- g_pLightMap[Index]->LockRect( 0, &d3dlr, 0, 0 );
- DWORD *pDst = (DWORD *)d3dlr.pBits;
-
- for (int x=0;x<256;x++)
- {
- for (int y=0;y<256;y++)
- {
- pDst[x*256+y] = (255 << 24 | L.Texel[y][x][0] << 16 |
- L.Texel[y][x][1] << 8 |
- L.Texel[y][x][2] );
-
- }
- }
-
- LogPrint(" Zatvaram lightmapu");
- g_pLightMap[Index]->UnlockRect (0);
-
- sprintf(cBuf,"media/light%d.bmp",Index);
- D3DXSaveTextureToFile(cBuf,D3DXIFF_BMP,g_pLightMap[Index],NULL);
-
-
-
- }
-
- //------------------------------------------------------------------
- // Name: CreateVertexBuffer()
- // Desc: Vytvori Vertex Buffer
- //------------------------------------------------------------------
- void BSP::CreateVertexBuffer()
- {
-
- if (FAILED(g_pd3dDevice->CreateVertexBuffer(NumFaces*3*sizeof(CUSTOMVERTEXBSP),
- D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEXBSP,
- D3DPOOL_DEFAULT, &g_pVB, NULL )))
- {
- LogPrint(" VertexBuffer: FAILED");
- }
- else
- {
- LogPrint(" VertexBuffer: OK");
- }
-
- }
-
- //------------------------------------------------------------------
- // Name: FillVertexBuffer()
- // Desc: naplni vertex buffer
- //------------------------------------------------------------------
- void BSP::FillVertexBuffer()
- {
- //pomocne premenne
- int ActVertex = 0;
- int NumF = 0;
- int i,u,j;
-
- //reset pocitadla
- NumVisibleFaces = 0;
-
- //Vertex do ktoreho sa uklada
- CUSTOMVERTEXBSP *Vertex;
-
- //Otvor VB
- g_pVB->Lock(0, 0, (void**)&Vertex, 0 ) ;
-
- /////////
- //GROUP//
- /////////
- for (i=0;i<NumGroups;i++)
- {
- //nastavi pociatocnu hodnotu
- Group[i].StartVertex = ActVertex;
- NumF = 0;
-
- for (u=0;u<NumFaces;u++)
- {
- if (Face[u].Visible == true)
- {
- if (Face[u].Group == i)
- {
-
- //pocitadlo
- NumVisibleFaces++;
-
- for (j=0;j<3;j++)
- {
- //prida vertex do VB
- Vertex[ActVertex].pos = D3DXVECTOR3(Face[u].P[j].X,
- Face[u].P[j].Y,
- Face[u].P[j].Z);
-
- Vertex[ActVertex].tu1 = Face[u].T1[j].X;
- Vertex[ActVertex].tv1 = Face[u].T1[j].Y;
-
- Vertex[ActVertex].tu2 = Face[u].T2[j].X;
- Vertex[ActVertex].tv2 = Face[u].T2[j].Y;
-
- Vertex[ActVertex].color = 0xffffffff;
-
- ActVertex++;
- }
-
- NumF++;
- }
-
- }
-
- }
-
- Group[i].NumVisibleFaces = NumF;
-
-
- }
-
- //zatvor VB
- g_pVB->Unlock();
-
- }
-
- //------------------------------------------------------------------
- // Name: Render()
- // Desc: vyrenderuje
- //------------------------------------------------------------------
- void BSP::Render()
- {
-
- int i;
-
- //
- //Optimalizacia
- //
- Optimalize();
-
- //
- //vynuluje world maticu
- //
- D3DXMATRIXA16 NullMatrix;
- D3DXMatrixIdentity(&NullMatrix);
- g_pd3dDevice->SetTransform( D3DTS_WORLD, &NullMatrix);
-
- //
- //Napσnie VB
- //
- FillVertexBuffer();
- g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEXBSP));
- g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEXBSP);
-
- //
- //redenruje podla materialov
- //
-
- //0
- for (i = 0;i<NumGroups;i++)
- {
- if (Group[i].BlendType == 0)
- RenderGroup(i);
- }
-
- //1
- for (i = 0;i<NumGroups;i++)
- {
- if (Group[i].BlendType == 1)
- RenderGroup(i);
- }
-
- //2
- for (i = 0;i<NumGroups;i++)
- {
- if (Group[i].BlendType == 2)
- RenderGroup(i);
- }
-
- //
- //Render debug BSP NODES
- //
- /*
- for (i=0;i<NumNodes;i++)
- {
- if (Node[i].Leaf == true)
- DebugDrawBox(Node[i].Min,Node[i].Max);
- }*/
-
- //
- //Render debug BSP LEAFS
- /*
- for (i=0;i<NumLeafs;i++)
- {
- DebugDrawBox(Leaf[i].Min,Leaf[i].Max);
- }*/
-
- //
- //Reset
- //
- Engine.ResetToDefault();
-
- }
-
- //------------------------------------------------------------------
- // Name: RenderGroup()
- // Desc: Vybrederuje skupinu
- //------------------------------------------------------------------
- void BSP::RenderGroup(int Index)
- {
- //nastavi priesvitnos¥
- SetBlendMode(Group[Index].BlendType);
-
- //vyber textury
- g_pd3dDevice->SetTexture( 0, Group[Index].g_pTexture);
-
- //vyber LightMapy
- g_pd3dDevice->SetTexture( 1, g_pLightMap[Index]);
-
- g_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
- g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
-
- g_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX,1);
- g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED );
- g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
-
- //render
- g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, Group[Index].StartVertex , Group[Index].NumVisibleFaces );
-
- }
- //------------------------------------------------------------------
- // Name: OptimalizePVS()
- // Desc: Vyberie viditelne faces
- //------------------------------------------------------------------
- void BSP::OptimalizePVS()
- {
- int i,u;
-
- //oznaci vsetky ako neviditelne
- for( i=0;i<NumFaces;i++)
- Face[i].Visible = false;
-
- //zisti v ktorom liste sa nachadza kamera
- int LeafIndex = GetLeafIndex(Camera.Pos);
-
- //ak je kamera v solid vyjdi z funckie
- if (LeafIndex == -1)
- return;
-
- //kde sa nachadza kamera vsetko vidno
- for(u=0;u<Leaf[LeafIndex].NumFaces ;u++)
- Face[Leaf[LeafIndex].FaceList[u]].Visible = true;
-
- //pre vsetky vidite╛ne leafy
- ///////
- //PVS//
- ///////
- for (i=0;i<Leaf[LeafIndex].NumVisibleLeafs;i++)
- {
- int LIndex = Leaf[LeafIndex].VisibleLeafs[i];
-
- ////////////////////
- //Frustrum culling//
- ////////////////////
- if (Camera.FrustrumSphere(Leaf[LIndex].Centre,Leaf[LIndex].Radius) == true)
- {
- for(u=0;u<Leaf[LIndex].NumFaces ;u++)
- Face[Leaf[LIndex].FaceList[u]].Visible = true;
- }
- }
-
- ///////////////////
- //backface culing//
- ///////////////////
- for(i=0;i<NumFaces;i++)
- {
- if (Face[i].Visible == true)
- {
- if (PointPlane(Plane[Face[i].Plane ],Camera.Pos) < 0.0f)
- Face[i].Visible = false;
- }
- }
-
- }
-
-
- //------------------------------------------------------------------
- // Name: Optimalize()
- // Desc: Vyberie viditelne faces
- //------------------------------------------------------------------
- void BSP::Optimalize()
- {
- int i,u;
-
- //oznaci vsetky ako neviditelne
- for( i=0;i<NumFaces;i++)
- Face[i].Visible = false;
-
- ///////
- for (i=0;i<NumLeafs;i++)
- {
- ////////////////////
- //Frustrum culling//
- ////////////////////
- if (Camera.FrustrumSphere(Leaf[i].Centre,Leaf[i].Radius) == true)
- {
- for(u=0;u<Leaf[i].NumFaces ;u++)
- Face[Leaf[i].FaceList[u]].Visible = true;
- }
- }
-
- ///////////////////
- //backface culing//
- ///////////////////
- for(i=0;i<NumFaces;i++)
- {
- if (Face[i].Visible == true)
- {
- if (PointPlane(Plane[Face[i].Plane ],Camera.Pos) < 0.0f)
- Face[i].Visible = false;
- }
- }
-
- }
-
- //------------------------------------------------------------------
- // Name: NoOptimalize()
- // Desc: neoptimalizuje
- //------------------------------------------------------------------
- void BSP::NoOptimalize()
- {
- //oznaci vsetky ako neviditelne
- for(int i=0;i<NumFaces;i++)
- Face[i].Visible = true;
-
- }
-
-
- //------------------------------------------------------------------
- // Name: SetBlendMode()
- // Desc: Nastavi priesvitnos¥ podla Indexu
- //------------------------------------------------------------------
- void BSP::SetBlendMode(int BlendType)
- {
- switch (BlendType)
- {
-
- case 0: //bez priesvitnosti
- Engine.SetBlendNone();
- break;
- case 1: //transparent
- Engine.SetBlendTrans();
- break;
- case 2: //one
- Engine.SetBlendOne();
- break;
- }
-
- }
-
- //------------------------------------------------------------------
- // Name: ReadNode()
- // Desc: precita nodu
- //------------------------------------------------------------------
- void BSP::ReadNode()
- {
- RBSPNODE N;
- int Index;
-
- fread(&N,sizeof(RBSPNODE),1,FileBsp);
-
- Index = N.Index;
-
- Node[Index].BackIndex = N.BackIndex ;
- Node[Index].FrontIndex = N.FrontIndex ;
- Node[Index].Leaf = N.Leaf ;
- Node[Index].LeafIndex = N.LeafIndex ;
- Node[Index].Solid = N.Solid;
- Node[Index].Radius = N.Radius ;
- Node[Index].Min = N.Min ;
- Node[Index].Max = N.Max ;
- Node[Index].Centre = N.Centre ;
- Node[Index].Root = N.Root ;
-
- }
-
- //------------------------------------------------------------------
- // Name: ReadLeaf()
- // Desc: precita list
- //------------------------------------------------------------------
- void BSP::ReadLeaf()
- {
- RBSPLEAF L;
- int Index;
-
- //nacita leaf
- fread(&L,sizeof(RBSPLEAF),1,FileBsp);
-
- Index = L.Index;
-
- Leaf[Index].FaceList = L.FaceList ;
- Leaf[Index].NumFaces = L.NumFaces ;
- Leaf[Index].VisibleLeafs = L.VisibleLeafs ;
- Leaf[Index].NumVisibleLeafs = L.NumVisibleLeafs ;
- Leaf[Index].Centre = L.Centre ;
- Leaf[Index].Max = L.Max ;
- Leaf[Index].Min = L.Min ;
- Leaf[Index].Radius = L.Radius ;
-
- //nacita face list leafu
- Leaf[Index].FaceList = new int [Leaf[Index].NumFaces];
- fread(&Leaf[Index].FaceList[0],sizeof(int),Leaf[Index].NumFaces,FileBsp);
-
- //nacita PVS
- Leaf[Index].VisibleLeafs = new int [Leaf[Index].NumVisibleLeafs ];
- fread(&Leaf[Index].VisibleLeafs[0],sizeof(int),Leaf[Index].NumVisibleLeafs,FileBsp);
- }
-
- //------------------------------------------------------------------
- // Name: GetLeafIndex()
- // Desc: zisti v akom liste sa nachadza bod
- //------------------------------------------------------------------
- int BSP::GetLeafIndex(VECTOR3D P)
- {
-
- int NIndex = 0; //index nody
- int PlaneIndex;
- float D; //vzdialenos¥ od roviny
-
- while(1==1)
- {
-
- PlaneIndex = Node[NIndex].Root;
-
- //solid
- if (Node[NIndex].Solid == true)
- return -1;
-
- //leaf
- if (Node[NIndex].Leaf == true)
- return Node[NIndex].LeafIndex ;
-
- D = PointPlane(Plane[PlaneIndex],P);
-
- //posle do front nody
-
- if (D>0.0f)
- {
- NIndex = Node[NIndex].FrontIndex ;
- continue;
- }
-
- //posle do back nody
- if (D<0.0f)
- {
- NIndex = Node[NIndex].BackIndex ;
- continue;
- }
-
- if (D == 0.0f)
- break ;
-
- }
-
- return -1;
-
- }
-
- //------------------------------------------------------------------
- // Name: SetTexture()
- // Desc: nastavi texturu
- //------------------------------------------------------------------
- void BSP::SetTexture(int ToGroup,LPDIRECT3DTEXTURE9 Tex)
- {
- Group[ToGroup].g_pTexture = Tex;
- }
-
-
-
-